1. /* smmreadn.cpp by K.Tsuru */
  2. // function ID = 005, 006 DRADIX
  3. #ifndef SN_H
  4. #include "sn.h"
  5. #endif
  6. /****************************************************************************
  7. SNManager class
  8. ReadNumber
  9. Read a SNumber data from a file.
  10. It reads number(s) such as integer, fraction or real from a file and returns
  11. the pointer to constant literal.If you want to receive it as a literal please
  12. write such as
  13. const char* str;
  14. str = SNManager::ReadNumber(fname);
  15. If you want a direct substitution
  16. SLong a;
  17. a = a.ReadNumber(fname);
  18. a.CloseReadNumber();
  19. [Notes on making files]
  20. Comment is allowed to insert.However the first character must be an alphabet,
  21. namely the line which begins with an alphabet is passed to the end.If the
  22. designated file cannot be opened or is not a number file it abnormally
  23. terminates the program. It can read "maxDigits"(defined in memblock.h) degits at
  24. the maximum.
  25. ----- An example of continuous read. --------
  26. SLong f, r;
  27. const char* num = f.ReadNumber(fname);
  28. while(num != NULL){
  29. r = num;
  30. r.Puts();
  31. num = r.ReadNumber(NULL);
  32. }
  33. ****************************************************************************/
  34. /**** static objects and functions *******************************************/
  35. static char* readBuff = NULL;
  36. static FILE* readStream = NULL;
  37. static int openFile = -1;
  38. // '/', '(', ')': for SFraction
  39. static const char* ok = " +-/.eE"; //the list of character for the number
  40. static const char* skip = " \\()\n\r"; //the list of character for the skip
  41. enum{ NUM_END = 1, SKIP, VALID};
  42. static void CloseReadFile(){
  43. if(readStream != NULL) fclose(readStream);
  44. openFile = 0; readStream = NULL;
  45. }
  46. // function ID = 006
  47. void SNManager::CloseReadNumber(){
  48. if(openFile < 0) return;
  49. CloseReadFile(); openFile = -1;
  50. delete[] readBuff; readBuff = NULL;
  51. }
  52. // fs : file or character's information.
  53. static int ReadDigit(int* fs){
  54. int c = fgetc(readStream);
  55. *fs = VALID;
  56. if( strchr(skip, c) != NULL ) *fs = SKIP;
  57. else if(c == EOF) *fs = EOF; //This must have priority over the following.
  58. else if(!isdigit(c) && (strchr(ok, c) == NULL)) *fs = NUM_END;
  59. return c;
  60. }
  61. //search the beginning of number
  62. static int SearchBegin(){
  63. const char* const begin = "+-."; //character set of bigining of number except digit
  64. int c;
  65. do{
  66. c = fgetc(readStream);
  67. if(isalpha(c)){ // A comment begins.
  68. while(1){
  69. c = fgetc(readStream);
  70. if( (c == '\n') || (c == '\r' ) || (c == EOF) ) break;
  71. }
  72. }
  73. } while(!isdigit(c) && (strchr(begin, c) == NULL) && (c != EOF));
  74. if(c != EOF) ungetc(c, readStream); //push back by a character
  75. return c;
  76. }
  77. static ulong NumLength(ulong maxLen){ // ver. 2.17, change "long" to "ulong"
  78. ulong len = 0; // It is remaked to partially read up to "maxLen".
  79. long top = ftell(readStream);
  80. int k;
  81. if(maxLen == 0) maxLen = ULONG_MAX;
  82. while(1){
  83. ReadDigit(&k);
  84. if( (k == EOF) || (k == NUM_END) || (len == maxLen) ) break;
  85. if(k != SKIP) len++;
  86. }
  87. fseek(readStream, top, SEEK_SET); // Restore file pointer.
  88. return len;
  89. }
  90. /*** Main body ********************************************************/
  91. // function ID = 005
  92. const char* SNManager::ReadNumber(const char* fname, uint size, int del){
  93. delete[] readBuff;
  94. readBuff = NULL; //Considering continuous call it frees memory first.
  95. if(fname != NULL){
  96. CloseReadFile(); // close previous file
  97. readStream = fopen(fname, "rt");
  98. if(readStream == NULL){
  99. fprintf(stderr, "Cannot open file : %s.\n", fname);
  100. exit(EXIT_FAILURE);
  101. }
  102. } else if(readStream == NULL){
  103. // fname == NULL the error of usage of continuous reading
  104. fprintf(stderr, "Did not open a number file yet.\n");
  105. exit(EXIT_FAILURE);
  106. }
  107. if( SearchBegin() == EOF){
  108. if(openFile <= 0){
  109. fprintf(stderr, "%s is not a number file.\n", fname);
  110. exit(EXIT_FAILURE);
  111. }
  112. CloseReadNumber();
  113. return NULL;
  114. }
  115. ulong readSize = (ulong)size*(ulong)DFIGURES, len = 0;
  116. ulong fsize = NumLength(readSize); //By reading through the file it gets the length.
  117. if(size && (fsize > readSize) ) fsize = readSize;
  118. if(fsize + 1uL > maxDigits) SetError(TOO_LONG,"ReadNumber", 5);//"maxDigits" in "membock.h"
  119. readBuff = new char[(uint)fsize+1]; // fsize + 1 <= UINT_MAX
  120. int c, k;
  121. while(1){
  122. c = ReadDigit(&k);
  123. if( (k == EOF) || (k == NUM_END) || (len == fsize) ){
  124. readBuff[len] = '\0';
  125. break;
  126. }
  127. if(k != SKIP) readBuff[len++] = (char)c;
  128. }
  129. if( size && (k != NUM_END) ){ //pass to the top of next data
  130. while(1){
  131. c = ReadDigit(&k);
  132. if( (k == EOF) || (k == NUM_END) ) break;
  133. }
  134. }
  135. if(k != EOF){ // data remains
  136. ungetc(c, readStream); // push back a character
  137. openFile = 1;
  138. } else CloseReadFile(); // set "openFile = 0"
  139. if(del && (fname != NULL) ){
  140. CloseReadFile();
  141. if( remove(fname) ) perror("Delete file");
  142. }
  143. return readBuff;
  144. }

smmreadn.cpp : last modifiled at 2017/06/23 10:37:54(4,952 bytes)
created at 2016/04/11 11:36:47
The creation time of this html file is 2017/10/27 10:59:17 (Fri Oct 27 10:59:17 2017).